#include "heaptimer.h"
void CHeapTimer::swim(size_t i) //上浮
{
    assert(i >=0 && i < m_heap.size());
    while (i > 0)
    {
        size_t parent = (i -1) /2;
        if (m_heap[parent] < m_heap[i])
        break;

    }
    
}
void CHeapTimer::swapNode(size_t i, size_t j)
{
    assert(i>=0 && i < m_heap.size());
    assert(j>=0 && j < m_heap.size());
    std::swap(m_heap[i], m_heap[j]);
    m_ref[m_heap[i].id] = i;
    m_ref[m_heap[j].id] = j;
}

//下沉
bool CHeapTimer::sink(size_t index, size_t n)
{
    assert(index >=0 && index <m_heap.size());
    assert(n>=0 && n<= m_heap.size());
    size_t i = index;
    while (i*2 + 1 <n)
    {
       size_t left = i*2 +1;
       size_t right = i*2 +2;
       size_t older = left;
       if (right < n && m_heap[right] < m_heap[older])
       {
           older = right;
       }
       if (m_heap[i] < m_heap[older])
       break;
       swapNode(i, older);
       i = older;
    }
    return i > index;
}
//添加新的时间节点
void CHeapTimer::add(int id, int timeout, const TimeoutCallBack& func)
{
    assert(id >=0);
    size_t i;
    if(m_ref.count(id) == 0)
    {
        i = m_heap.size();
        m_ref[id] = i;
        m_heap.push_back({ id,Clock::now() + MS(timeout),func });
        swim(i);
    }
    else //若已经存在，则更新阻塞时间
    {
        i = m_ref[id];
        m_heap[i].expires =  Clock::now() + MS(timeout);
        m_heap[i].func = func;
        if (!sink(i, m_heap.size()))
        {
            swim(i);
        }
    }
}
//删除指定位置的时间节点
void CHeapTimer::del(size_t i) 
{
    assert(!m_heap.empty() && i >= 0 && i < m_heap.size());
    size_t n = m_heap.size() -1;
    if (i < n)
    {
        swapNode(i, n);
        if(!sink(i,n))
        {
            swim(i);
        }
    }
    m_ref.erase(m_heap.back().id);
    m_heap.pop_back();
} 
//删除指定序号的时间节点
void CHeapTimer::doWork(int id)
{
    if(m_heap.empty() || m_ref.count(id) == 0)
    {
        return;
    }
    size_t i = m_ref[id];
    TimerNode cur = m_heap[i];
    cur.func();
    del(i);
}
//更新阻塞时间
void CHeapTimer::adjust(int id, int timeout)
{
    assert(!m_heap.empty() && m_ref.count(id) >0 );
    m_heap[m_ref[id]].expires = Clock::now() + MS(timeout);
    sink(m_ref[id], m_heap.size());
}
//清除超时节点
void CHeapTimer::tick()
{
    if(m_heap.empty())
    {
        return;
    }
    while(!m_heap.empty())
    {
        TimerNode cur = m_heap.front();
        if(std::chrono::duration_cast<MS>(cur.expires - Clock::now()).count() >0)
        {
            break;
        }
        cur.func();
        pop();
    }
}
//删除堆顶节点
void CHeapTimer::pop()
{
    assert(!m_heap.empty());
    del(0);
}

void CHeapTimer::clear()
{
    m_ref.clear();
    m_heap.clear();
}

//得到堆顶点节点剩余的阻塞时间(心搏函数)
int CHeapTimer::getNextTick()
{
    tick();
    size_t res = -1;
    if(!m_heap.empty())
    {
        res = std::chrono::duration_cast<MS>(m_heap.front().expires - Clock::now()).count();
        if(res < 0)
         res = 0;
    }
    return res;
}